package cn.vc.shop.service;

import cn.vc.basicmodule.entity.Result;
import cn.vc.shop.entity.dto.CommodityDto;
import cn.vc.shop.entity.po.Commodity;
import cn.vc.shop.entity.po.OrderForGoods;
import cn.vc.shop.entity.po.Shop;
import cn.vc.shop.mapper.CommodityMapper;
import cn.vc.shop.mapper.ShopMapper;
import cn.vc.shop.util.SnowFlakeUtil;
import cn.vc.wallet.feign.clients.WalletClient;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CommodityService extends ServiceImpl<CommodityMapper, Commodity> {
    private final CommodityMapper commodityMapper;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private WalletClient walletClient;
    @Autowired
    private OrderForGoodsService orderForGoodsService;

    public CommodityService(CommodityMapper commodityMapper) {
        this.commodityMapper = commodityMapper;
    }



    public boolean insert(Commodity commodity) {
        return commodityMapper.insert(commodity)==1;
    }



    public boolean deleteById(Long id) {
        return commodityMapper.deleteById(id)==1;
    }


    /**
     * 查询所有
     * @return
     */
    public List<Commodity> selectAll() {
        return commodityMapper.selectList(null);
    }
    /**
     * 查询商铺ID的全部商品
     */
    public List<CommodityDto> selectByShopId(Long shopId) {
        LambdaQueryWrapper<Commodity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Commodity::getShopId, shopId);
        List<Commodity> commodityList = commodityMapper.selectList(lqw);
        // 返回空列表
        if (commodityList==null||commodityList.isEmpty()) return Collections.emptyList();
        List<CommodityDto> commodityDtoList = commodityList.stream()
                .map(CommodityDto::new)
                .collect(Collectors.toList());
        return commodityDtoList;
    }
    /**
     * 查询ID商品
     * @return
     */
    public CommodityDto selectById(Long id) {
        Commodity commodity = commodityMapper.selectById(id);
        if (commodity==null) return null;
        CommodityDto commodityDto = new CommodityDto(commodity);
        return commodityDto;
    }
    public Commodity selectByName(String name) {
        LambdaQueryWrapper<Commodity> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Commodity::getName, name);
        return commodityMapper.selectOne(lqw);
    }




    public boolean updateUrlById(Commodity commodity) {
        return commodityMapper.updateById(commodity)==1;
    }


    /**
     * 购买秒杀类商品
     * @param userId 用户ID
     * @param commodityId 商品ID
     * @param num 购买数量
     * @return 订单
     */
    @Transactional
    public Result<OrderForGoods> buySeckill(Long userId, Long commodityId, Integer num) {
        // 参数为空或错误，返回
        if (userId==null&&commodityId==null&&num<1) return new Result<>(0, null, "数据错误！");
        OrderForGoods orderForGoods;
        // 创建锁对象
        Lock lock = redissonClient.getLock("commodity:buy:seckill:"+commodityId);
        try {
            // 加锁
            lock.lock();
            Commodity commodity = commodityMapper.selectById(commodityId);
            // 判断是否可以供货
            Long commodityNum = commodity.getNum();
            if (commodityNum<num) {
                log.debug("商品{}不够或已售完", commodityId);
                return new Result<>(0, null, "商品已售空");
            }
            // 判断是否限额
            if (commodity.getLimited()>-1&& orderForGoodsService.selectIsLimited(userId,commodityId, commodity.getLimited())) {
                return new Result<>(0, null, "该商品购买次数已限额！");
            }
            // 减少数量
            commodity.setNum(commodityNum-num);
            // 创建订单
            orderForGoods = new OrderForGoods();
            orderForGoods.setId(SnowFlakeUtil.getID());
            orderForGoods.setUserId(userId);
            orderForGoods.setCommodityId(commodityId);
            orderForGoods.setCommodityName(commodity.getName());
            orderForGoods.setNum(num);
            orderForGoods.setUnitPrice(commodity.getPrice());
            orderForGoods.setTotalPrice(commodity.getPrice()*num);
            // 2、扣除钻石 并 扣除库存 成功
            if ((orderForGoods.getTotalPrice()==0 || walletClient.diamondDeduction(userId, orderForGoods.getTotalPrice().longValue()))
                    && commodityMapper.updateById(commodity)==1) {
                return new Result<>(1, orderForGoods, "购买成功！");
            } else {
                return new Result<>(0, null, "余额不足！");
            }
        } finally {
            // 解锁
            lock.unlock();
        }
    }

    /**
     * 购买普通类商品
     * @param userId 用户ID
     * @param commodityId 商品ID
     * @param num 购买数量
     * @return 订单
     */
    @Transactional
    public Result<OrderForGoods> buyCommon(Long userId, Long commodityId, Integer num) {
        if (userId==null&&commodityId==null&&num<1) return new Result<>(0, null, "数据错误！");
        Commodity commodity = commodityMapper.selectById(commodityId);
        // 判断是否可以供货
        Long commodityNum = commodity.getNum();
        if (commodityNum<num) {
            log.debug("商品{}不够或已售完", commodityId);
            return new Result<>(0, null, "商品已售空");
        }
        // 判断是否限额
        if (commodity.getLimited()>-1&& orderForGoodsService.selectIsLimited(userId,commodityId, commodity.getLimited())) {
            return new Result<>(0, null, "该商品购买次数已限额！");
        }
        // 减少数量
        commodity.setNum(commodityNum-num);
        // 创建订单
        OrderForGoods orderForGoods = new OrderForGoods();
        orderForGoods.setId(SnowFlakeUtil.getID());
        orderForGoods.setUserId(userId);
        orderForGoods.setCommodityId(commodityId);
        orderForGoods.setCommodityName(commodity.getName());
        orderForGoods.setNum(num);
        orderForGoods.setUnitPrice(commodity.getPrice());
        orderForGoods.setTotalPrice(commodity.getPrice()*num);
        // 2、扣除钻石 并 扣除库存 成功
        if ((orderForGoods.getTotalPrice() == 0 || walletClient.diamondDeduction(userId, orderForGoods.getTotalPrice().longValue()))
                && commodityMapper.updateById(commodity)==1) {
            return new Result<>(1, orderForGoods, "购买成功！");
        } else {
            return new Result<>(0, null, "余额不足！");
        }
    }

    /**
     * 获取订单号
     * @param id 商品ID
     * @return
     */
    protected String getOrderNumber(Long id) {
        SimpleDateFormat formatter= new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date(System.currentTimeMillis());
        return formatter.format(date)+id;
    }

}
